home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir34
/
pbformt2.zip
/
PBFORMAT.BAS
Wrap
BASIC Source File
|
1993-10-14
|
15KB
|
443 lines
'PBFORMAT.BAS by Thaddy de Koning, based on:
'QBFORMAT.BAS by Cornel Huth.
'14-October-1993 - Modified to format 2.8MB Floppies by Allen Hillman
'format MS-DOS floppy disks using PB and BIOS
%F360 = &HFD
%F1200 = &HF9
'NOTE: Original code contained mayor BUG with 3.5 inch types
'Fixed that in this PB version.
'*** %F720 media byte is NEGATIVE to differ from %F1200 ***
%F720 = -&HF9
%F1440 = &HF0
'*** %F2880 media byte is negative to differ from %F1440
%F2880 = -&HF0
%RETRIES = 5 '%RETRIES on BIOS error
$INCLUDE "c:\pb3\REGNAMES.INC"
TYPE ADDRFIELDtype
track AS STRING * 1
head AS STRING * 1
sector AS STRING * 1
bytesec AS STRING * 1
END TYPE '4
TYPE INFOtype
OEM AS STRING * 8 'system name
BS AS WORD 'bytes/sector
SC AS BYTE 'STRING * 1 'sectors/cluster
RS AS WORD 'reserved sectors
NF AS BYTE 'STRING * 1 'FATs
DE AS WORD 'root directory entries
TS AS WORD 'total sectors on volume
MB AS STRING * 1 'media byte
SF AS WORD 'sectors/FAT
ST AS WORD 'sectors/track
NH AS WORD 'heads
HS AS WORD 'hidden sectors
END TYPE '27
TYPE BOOTRECtype
jmp AS STRING * 3
parms AS INFOtype
code AS STRING * 482
END TYPE '512
DEFINT A-Z
'INT 1Eh disk parameter table vectors
DIM OldDPTseg AS SHARED WORD, OldDPToff AS SHARED WORD
DIM NewDPTseg AS SHARED WORD, NewDPToff AS SHARED WORD
'Number of tracks on media
SHARED NoTracks
'format info for media
DIM Info AS SHARED INFOtype
'interface with INTERRUPTX routine
'boot record buffer
DIM BootRec AS SHARED BOOTRECtype
'sector buffer to write FAT & root directory sectors
DIM SectorBuff AS SHARED STRING * 512
$STATIC
'Allocate address field data to max possible sectors per track
DIM AddrField(1 TO 36) AS SHARED ADDRFIELDtype
BootSector:
DATA &HEB,&H3E,&H90,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &HA,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H2B,&HC0,&H8E,&HD0,&HBC,&H0,&H7C,&HB8,&HC0,&H7,&H8E,&HD8,&H8E,&HC0,&HBE,&H3
DATA &H0,&HBF,&HAF,&H0,&HB9,&H4,&H0,&HF3,&HA5,&HBE,&HAF,&H0,&HB4,&HE,&H8A,&H4
DATA &HA,&HC0,&H74,&H7,&H56,&HCD,&H10,&H5E,&H46,&HEB,&HF1,&HFC,&HBE,&H7A,&H0,&HBF
DATA &H0,&H2,&HB9,&H0,&H2,&HF3,&HA4,&HE9,&H86,&H1,&HB8,&H1,&H2,&H2B,&HDB,&HB9
DATA &H1,&H0,&HBA,&H50,&H0,&HCD,&H13,&H72,&HC,&HBB,&HFE,&H1,&H81,&H3F,&H55,&HAA
DATA &H75,&H3,&HE9,&HE5,&HFD,&HBE,&H58,&H2,&HB4,&HE,&H8A,&H4,&HA,&HC0,&H74,&H7
DATA &H56,&HCD,&H10,&H5E,&H46,&HEB,&HF1,&H2B,&HC0,&HCD,&H16,&HCD,&H19,&HCD,&H18,&H20
DATA &H20,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H6E,&H6F,&H6E,&H2D,&H62,&H6F,&H6F,&H74
DATA &H61,&H62,&H6C,&H65,&H20,&H64,&H69,&H73,&H6B,&H20,&H69,&H6E,&H20,&H41,&H3A,&HD
DATA &HA,&H0,&H4E,&H6F,&H20,&H62,&H6F,&H6F,&H74,&H20,&H64,&H69,&H73,&H6B,&H20,&H66
DATA &H6F,&H75,&H6E,&H64,&H2C,&H20,&H72,&H65,&H70,&H6C,&H61,&H63,&H65,&H20,&H61,&H6E
DATA &H64,&H20,&H70,&H72,&H65,&H73,&H73,&H20,&H61,&H20,&H6B,&H65,&H79,&H20,&HD,&HA
DATA &HD,&HA,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H55,&HAA
'============================================================================
'The following code is a sample run to format a disk
'All other code can be compiled and put in a library
'format test drive A: double-sided/36-sector media (2880K)
drive = 0: media = %F1440
CLS : DO: LOOP WHILE INKEY$ <> ""
INPUT "Insert disk to format in drive A: and press a key", a$
INPUT "Press a key to start PBFORMAT", a$
PRINT
xerr = PBFORMAT(drive, media)
IF xerr THEN
errl = xerr \ 256
errc = xerr AND 255
PRINT "*** Error level:"; errl; " code:"; errc
ELSE
PRINT "done."
END IF
STOP
SUB ComputeCHS (LogSec, cyl, hd, sec)
'convert a DOS logical sector to BIOS form
CylSec = Info.ST * Info.NH
cyl = LogSec \ CylSec
rm = LogSec - (cyl * CylSec)
hd = rm \ Info.ST
sec = rm - (hd * Info.ST) + 1
END SUB
FUNCTION FormatDisk (drive)
'format a track at a time a side at a time
'any error aborts format,diskette presumed unreliable
'retry format 1 or 2 more times before trashing the diskette
y=Pos(0)
x=CSRLIN
FOR track = 0 TO (NoTracks - 1)
LOCATE x,y:PRINT "Formatting track:";track
'This is where you insert any printed info.
'If you don't want it, remove it......
FOR head = 0 TO (Info.NH - 1)
FOR i = 1 TO %RETRIES
xerr = FormatTrack(drive, track, head)
IF xerr = 0 THEN EXIT FOR
NEXT
IF xerr THEN FormatDisk = xerr: EXIT FUNCTION
NEXT
NEXT
FormatDisk = 0
END FUNCTION
FUNCTION FormatTrack (drive, track, head)
'Initialize address field for each sector on this track
FOR sec = 1 TO Info.ST
AddrField(sec).track = CHR$(track)
AddrField(sec).head = CHR$(head)
AddrField(sec).sector = CHR$(sec)
AddrField(sec).bytesec = CHR$(2) 'bytecode 2 = 512-byte sector
NEXT
reg %ax, &H500 + Info.ST 'format track with sectors/track
reg %cx, (track * 256) + 1 'track to format,start with sector 1
Reg %dx, (head * 256) + drive 'head,drive
Reg %es, VARSEG(AddrField(1)) 'point to address field data
Reg %bx, VARPTR(AddrField(1))
CALL INTERRUPT &H13
cf = Reg (%flags) AND 1 'cf=1 if disk error
IF cf THEN
E?? = Reg (%ax)
'IF e& < 0 THEN e& = e& + 65536
SHIFT RIGHT e??,8 ' = e& \ 256 'return with status byte
Formattrack=e??
ResetFDC drive
ELSE
Reg %ax, &H400 + Info.ST 'ok, verify track integrity-
CALL INTERRUPT &H13 '-optional but recommended on format
cf = Reg (%flags) AND 1 'cf=1 if disk error
IF cf THEN
e?? = Reg (%ax)
SHIFT RIGHT e??,8 ' = e?? \ 256 'return with status byte
Formattrack=e??
ResetFDC drive
ELSE
FormatTrack = 0 'format ok
END IF
END IF
END FUNCTION
SUB InitFormatParms (media)
'set up media's format data
Info.OEM = "IBM PB3" 'avoid changing 'IBM'
Info.BS = 512
Info.RS = 1
Info.NF = 2 'CHR$(2)
Info.NH = 2
Info.HS = 0
SELECT CASE media
CASE %F360
Info.SC = 2 'CHR$(2)
Info.DE = 112
Info.TS = 720
Info.MB = CHR$(%F360)
Info.SF = 2
Info.ST = 9
CASE %F1200
Info.SC = 1 'CHR$(1)
Info.DE = 224
Info.TS = 2400
Info.MB = CHR$(%F1200)
Info.SF = 7
Info.ST = 15
CASE %F720
Info.SC = 2 'CHR$(2)
Info.DE = 112
Info.TS = 1440
Info.MB = CHR$(ABS(%F720))
Info.SF = 3
Info.ST = 9
CASE %F1440
Info.SC = 1 'CHR$(1)
Info.DE = 224
Info.TS = 2880
Info.MB = CHR$(%F1440)
Info.SF = 9
Info.ST = 18
case %F2880
Info.SC = 2 'CHR$(2)
Info.DE = 240
Info.TS = 5760
Info.MB = CHR$(ABS(%F2880))
Info.SF = 9
Info.ST = 36
CASE ELSE
Info.OEM = ""
Info.BS = 0
Info.RS = 0
Info.NF = 0 'CHR$(0)
Info.NH = 0
Info.HS = 0
Info.SC = 0 'CHR$(0)
Info.DE = 0
Info.TS = 0
Info.MB = CHR$(0)
Info.SF = 0
Info.ST = 0
END SELECT
NoTracks = Info.TS \ Info.NH \ Info.ST
NewDPTseg = 0 'INT 1Eh vector
NewDPToff = 0 'new -> disk parameter table for formatted media
OldDPTseg = 0 'original-
OldDPToff = 0 '-vector
END SUB
FUNCTION PBFORMAT (drive, media)
'control routine
xerr = ValidateDisk(drive, media)
IF xerr = 0 THEN xerr = FormatDisk(drive) ELSE level = 1
IF xerr = 0 THEN xerr = WriteBoot(drive) ELSE IF level = 0 THEN level = 2
IF xerr = 0 THEN xerr = WriteFAT(drive) ELSE IF level = 0 THEN level = 3
IF xerr = 0 THEN xerr = WriteDir(drive) ELSE IF level = 0 THEN level = 4
IF xerr THEN IF level = 0 THEN level = 5
'reset INT 1Eh vector to original,check both for <>0
IF OldDPTseg <> 0 OR OldDPToff <> 0 THEN
Reg %ax, &H251E
Reg %ds, OldDPTseg
Reg %dx, OldDPToff
CALL INTERRUPT &H21
END IF
PBFORMAT = (level * 256) + xerr
'sample call
'xerr = PBFORMAT(drive, media)
'IF xerr THEN errl = xerr \ 256: errc = xerr AND 255
'level error codes
'0:no error
'1:validate error
'2:format error
'3:boot record write error
'4:FAT write error
'5:directory write error
'floppy disk error codes (xerr,in decimal):
'0:no error
'1:invalid function request
'2:address mark not found
'3:write protected
'4:sector not found
'6:diskette changed
'8:DMA overrun
'9:DMA boundary error
'12:media type not available
'16:bad CRC
'32:diskette controller failed
'64:seek failed
'128:time-out/drive not ready
END FUNCTION
SUB ResetFDC (drive)
'reset the controller after any BIOS FDC error
Reg %ax, 0
Reg %dx, drive
CALL INTERRUPT &H13
END SUB
FUNCTION ValidateDisk (drive, media)
'check if media supported by program,by drive,and if drive is ready
InitFormatParms media
IF Info.ST THEN
'check to see if there is CMOS RAM (means we have an AT BIOS)
OUT &H70, &H10
CMOS = (INP(&H71) <> &HFF)
ResetFDC drive
IF CMOS THEN
'get original INT 1Eh vector to disk parameter table
Reg %ax, &H351E
CALL INTERRUPT &H21
OldDPTseg = Reg (%es)
OldDPToff = Reg (%bx)
'set media type for format on AT BIOS/multi-media drive
'let BIOS determine if drive can format media with a DPT in BIOS ROM
'Reg %ax, &H1800
'Reg %cx, ((NoTracks - 1) * 256) + Info.ST
'Reg %dx, drive
FOR checks = 1 TO %RETRIES 'zerr=0 no error
Reg %ax, &H1800
Reg %cx, ((NoTracks - 1) * 256) + Info.ST
Reg %dx, drive
CALL INTERRUPT &H13
zerr = Reg (%ax) \ 256 'zerr=&H0C unknown media/maybe invalid CMOS
IF zerr THEN ResetFDC drive ELSE EXIT FOR
NEXT
'set INT 1Eh vector to this media's disk parameter table in BIOS ROM
IF zerr = 0 THEN
NewDPTseg = Reg (%es)
NewDPToff = Reg (%di)
Reg %ax, &H251E
Reg %ds, NewDPTseg
Reg %dx, NewDPToff
CALL INTERRUPT &H21
ELSE
OldDPTseg = 0
OldDPToff = 0
END IF
END IF
ELSE
zerr = &HC 'media not supported by program
END IF
'physical check for disk in the drive
IF zerr = 0 THEN
Reg %ax, &H401 'verify 1 sector from drive
Reg %cx, &H1 'track=0 sector=1
Reg %dx, drive 'head=0 drive=drive
FOR checks = 1 TO %RETRIES
CALL INTERRUPT &H13
IF Reg ((%flags) AND 1) THEN 'bad read
zerr = Reg (%ax)
'need to detect an unformatted disk
shift right zerr,8 ' = e?? \ 256
ResetFDC drive
ELSE
zerr = 0 'good read,already formatted disk in drive
EXIT FOR
END IF
NEXT
'zerr may be any of the BIOS diskette error codes if non-zero here
'address mark not found(2)=unformatted disk in drive
'sector not found(4)=wacko disk but okay to proceed
IF zerr = 2 OR zerr = 4 THEN zerr = 0
END IF
ValidateDisk = zerr
END FUNCTION
FUNCTION WriteBoot (drive)
RESTORE BootSector
'read default boot record data
DEF SEG = VARSEG(BootRec): offset = VARPTR(BootRec)
FOR i = 0 TO 511: READ byte: POKE offset + i, byte: NEXT: DEF SEG
'update OEM name and BIOS parameter block
BootRec.parms = Info
'write the boot record
FOR i = 1 TO %RETRIES
xerr = WriteBootSector(drive)
IF xerr = 0 THEN EXIT FOR
NEXT
WriteBoot = xerr
END FUNCTION
FUNCTION WriteBootSector (drive)
Reg %ax, &H300 + 1 'write 1 sector
Reg %cx, 1 'track 0,sector 1
Reg %dx, drive 'head 0,drive
Reg %es, VARSEG(BootRec) 'point to boot record data
Reg %bx, VARPTR(BootRec)
CALL INTERRUPT &H13
cf = Reg (%flags) AND 1 'cf=1 if disk error
IF cf THEN
e?? = Reg (%ax)
WriteBootSector = e?? \ 256 'return with status byte
ResetFDC drive
ELSE
WriteBootSector = 0 'ok
END IF
END FUNCTION
FUNCTION WriteDir (drive)
MID$(SectorBuff, 1, 1) = CHR$(0)
FOR i = 2 TO 512
IF (i - 1) MOD 32 = 0 THEN
MID$(SectorBuff, i, 1) = CHR$(0)
ELSE
MID$(SectorBuff, i, 1) = CHR$(&HF6)
END IF
NEXT
LogSec = Info.RS + Info.HS + (Info.SF * Info.NF) 'first logical dir sector
FOR i = 1 TO (Info.DE \ 16) 'sectors needed for root directory
ComputeCHS LogSec, cyl, hd, sec
FOR k = 1 TO %RETRIES
xerr = WriteSector(drive, cyl, hd, sec)
IF xerr = 0 THEN EXIT FOR
NEXT
IF xerr THEN WriteDir = xerr: EXIT FUNCTION
LogSec = LogSec + 1
NEXT
WriteDir = 0
END FUNCTION
FUNCTION WriteFAT (drive)
' do the hussle
FAT1$ = Info.MB + CHR$(255) + CHR$(255)
FAT2$ = CHR$(0) + CHR$(0) + CHR$(0)
FOR i = 1 TO 512: MID$(SectorBuff, i, 1) = CHR$(0): NEXT
LogSec = Info.RS + Info.HS 'first logical FAT sector
FOR i = 1 TO Info.NF
FOR j = 1 TO Info.SF
IF j = 1 THEN MID$(SectorBuff, 1) = FAT1$ ELSE MID$(SectorBuff, 1) = FAT2$
ComputeCHS LogSec, cyl, hd, sec
FOR k = 1 TO %RETRIES
xerr = WriteSector(drive, cyl, hd, sec)
IF xerr = 0 THEN EXIT FOR
NEXT
IF xerr THEN WriteFAT = xerr: EXIT FUNCTION
LogSec = LogSec + 1
NEXT
NEXT
WriteFAT = 0
END FUNCTION
FUNCTION WriteSector (drive, cyl, hd, sec)
'BIOS write a FAT or directory sector
Reg %ax, &H300 + 1
Reg %cx, (cyl * 256) + sec
Reg %dx, (hd * 256) + drive
Reg %es, VARSEG(SectorBuff)
Reg %bx, VARPTR(SectorBuff)
CALL INTERRUPT &H13
cf = Reg (%flags) AND 1
IF cf THEN
e?? = Reg (%ax)
WriteSector = e?? \ 256
ResetFDC drive
ELSE
WriteSector = 0
END IF
END FUNCTION